package com.easpeed.comon.utils

import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonObject
import com.google.gson.reflect.TypeToken
import java.lang.reflect.Modifier
import java.lang.reflect.Type

/**
 * Created by bigyu on 2022/5/17 14:40
 * com.ww.baselibrary.utils
 */
class GsonUtils {


    fun mGsonBuilder(): Gson? {
        return GsonBuilder()
            .create()
    }


    fun toJson(any: Any?): String? {
        return mGsonBuilder()?.toJson(any)
    }

    companion object {

        private var gson: Gson? = null

        @JvmStatic
        fun initGson(): Gson? {
            if (gson == null) {
                val builder = GsonBuilder()
                builder.excludeFieldsWithModifiers(
                    Modifier.FINAL,
                    Modifier.TRANSIENT,
                    Modifier.STATIC
                )
                builder.registerTypeAdapter(
                    object : TypeToken<MutableMap<String, Any?>>() {}.type,
                    MapTypeAdapter()
                )
                gson = builder.create()
            }
            return gson
        }

        @JvmStatic
        fun <T> parse(json: String?, clazz: Class<T>?): T? {
            try {
                initGson()
                return gson?.fromJson(json, clazz)
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return null
        }

        fun <T> parseType(json: String?, typeToken: Type): T? {
            try {
                initGson()
                return gson?.fromJson(json, typeToken)
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return null
        }

        fun <T> parseType(json: JsonObject?, typeToken: Type): T? {
            try {
                initGson()
                return gson?.fromJson(json, typeToken)
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return null
        }

        @JvmStatic
        fun <T> parseList(json: String?, clazz: Class<T>): List<T>? {
            initGson()
            val type: Type = ParameterizedTypeImpl(MutableList::class.java, arrayOf(clazz))
            return gson?.fromJson(json, type)
        }

        @JvmStatic
        fun <T> stringify(`object`: T): String? {
            return gson?.toJson(`object`)
        }

        @JvmStatic
        fun <T> stringifyList(objectList: List<T>?): String? {
            return gson?.toJson(objectList)
        }

        fun parseMap(json: String?): MutableMap<*, *>? {
            val type = MutableMap::class.java
            return parse(json, type)
        }
    }

}